#include "src/scene/color.h"

#include <iostream>
#include <cstdlib>

#include "src/defines/colors.h"
#include "src/scene/energyColor.h"

Color::Color(){
	red = 0.0;
	green = 0.0;
	blue = 0.0;
	alpha = 1.0;
}

Color::Color(const Color &_color){
    *this = _color;
}

Color::Color(const EnergyColor &_color){
    *this = _color;
}

Color::Color(const unsigned int &_color){
	switch(_color)
	{
	    case BLACK:
            red = 0;
            green = 0;
            blue = 0;
            break;
	    case RED:
            red = 1;
            green = 0;
            blue = 0;
            break;
	    case GREEN:
            red = 0;
            green = 1;
            blue = 0;
            break;
	    case BLUE:
            red = 0;
            green = 0;
            blue = 1;
            break;
	    case YELLOW:
            red = 1;
            green = 1;
            blue = 0;
            break;
	    case PINK:
            red = 1;
            green = 0;
            blue = 1;
            break;
	    case CYAN:
            red = 0;
            green = 1;
            blue = 1;
            break;
	    case WHITE:
            red = 1;
            green = 1;
            blue = 1;
            break;
	}
	alpha = 1.0;
}

Color::Color(const double &_r, const double &_g, const double &_b, const double &_a): red(_r), green(_g), blue(_b), alpha(_a){}

Color::~Color(){}

double Color::operator[](const unsigned int &_i) const
{
    switch(_i){
        case 0:
            return red;
            break;
        case 1:
            return green;
            break;
        case 2:
            return blue;
            break;
        case 3:
            return alpha;
            break;
    }
    std::cout <<"Erro no operador [] de Color!"<<std::endl;
    exit(1);
}

Color &Color::operator=(const Color &_c) {
	if(this != &_c) {
		red = _c.red;
		green = _c.green;
		blue = _c.blue;
		alpha = _c.alpha;
	}
	return *this;
}

Color &Color::operator=(const EnergyColor &_c) {
	if(this != &_c) {
		red = _c.red * _c.energy;
		green = _c.green * _c.energy;
		blue = _c.blue * _c.energy;
		alpha = _c.alpha * _c.energy;
	}
	return *this;
}

bool Color::operator==(const Color &_c) const {
    return  (red == _c.red) && (green == _c.green) && (blue == _c.blue) && (alpha == _c.alpha);
}

bool Color::operator!=(const Color &_c) const {
    return  (red != _c.red) || (green != _c.green) || (blue != _c.blue) || (alpha != _c.alpha);
}

Color Color::operator+(const Color &_color) const {
    double r = _color.red + red;
    double g = _color.green + green;
    double b = _color.blue + blue;
    double a = _color.alpha + alpha;

	return Color(r, g, b, a);
}

Color Color::operator-(const Color &_color) const {
    double r = red - _color.red;
    double g = green - _color.green;
    double b = blue - _color.blue;
    double a = alpha - _color.alpha;

	return Color(r, g, b, a);
}

Color Color::operator*(const Color &_color) const {
    double r = red * _color.red;
    double g = green * _color.green;
    double b = blue * _color.blue;
    double a = alpha * _color.alpha;

	return Color(r, g, b, a);
}

Color Color::operator*(const double &_d) const {
    double r = red * _d;
    double g = green * _d;
    double b = blue * _d;
    double a = alpha * _d;

	return Color(r, g, b, a);
}

Color Color::operator/(const double &_d) const {
    double r = red / _d;
    double g = green / _d;
    double b = blue / _d;
    double a = alpha / _d;

	return Color(r, g, b, a);
}

Color Color::truncate() const {
    double r, g, b, a;

    if(red > 1) r = 1.0;
    else if(red < 0) r = 0.0;
    else r = red;

    if(green > 1) g = 1.0;
    else if(green < 0) g = 0.0;
    else g = green;

    if(blue > 1) b = 1.0;
    else if(blue < 0) b = 0.0;
    else b = blue;

    if(alpha > 1) a = 1.0;
    else if(alpha < 0) a = 0.0;
    else a = alpha;

	return Color(r, g, b, a);
}

void Color::print() const {
    std::cout << "Cor [ " <<red << ", " << green << ", " << blue << ", " << alpha <<"]"<<std::endl;
}

GLfloat *Color::toGL(GLfloat _v[], double _kt) const
{
    _v[0] = red;
    _v[1] = green;
    _v[2] = blue;
    if(alpha == 1) _v[3] = 1 - _kt;
    else _v[3] = alpha;
//    if(_v[3] > 1) _v[3] = 1;
//    else (_v[3] < 0) _v[3] = 0;
    return _v;
}
